package net.lastcoder.ifserver.util;

import net.lastcoder.ifserver.Constants;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.CountingQuietWriter;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;
import org.apache.log4j.spi.LoggingEvent;

import java.io.File;
import java.io.IOException;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

/**本地的日志格式，每个一天都会生成一个新的文件
 * auth: WenYF
 * date: 2017/11/16
 */
public class LocalRollingFileAppender extends FileAppender {
    protected long maxFileSize = 10485760L;
    protected int maxBackupIndex = 5;
    // 今天的时间23:59:50
    protected long checkTime;
    protected String baseFilename;
    protected SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");;
    protected String lastDateName;

    public LocalRollingFileAppender() {
    }

    public LocalRollingFileAppender(Layout layout, String filename, boolean append) throws IOException {
        super(layout, filename, append);
    }

    public LocalRollingFileAppender(Layout layout, String filename) throws IOException {
        super(layout, filename);
    }

    @Override
    public void setFile(String file) {
        long time = System.currentTimeMillis();
        Date date = new Date(time);
        int hour = date.getHours();
        int minus = date.getMinutes();
        int seconds = date.getSeconds();

        long remainMiliseconds = Constants.DAY - (Constants.HOUR * hour + Constants.MINUTE * minus + Constants.SECOND * seconds);

        checkTime = time + remainMiliseconds - 10000;

        baseFilename = file.trim();
        lastDateName = sdf.format(new Date(checkTime));
        String val = baseFilename + "." + sdf.format(new Date(time));
        this.fileName = val;
    }

    public int getMaxBackupIndex() {
        return this.maxBackupIndex;
    }

    public long getMaximumFileSize() {
        return this.maxFileSize;
    }

    public void rollOver(boolean fullSize) {
        // 这个文件已经写满

        if (fullSize) {
            // 文件满了
            if(super.qw != null) {
                LogLog.debug("rolling over count=" + ((CountingQuietWriter)super.qw).getCount());
            }

            LogLog.debug("maxBackupIndex=" + this.maxBackupIndex);
            if(this.maxBackupIndex > 0) {
                // 删除最大的备份
                File file = new File(super.fileName + '.' + this.maxBackupIndex);
                if(file.exists()) {
                    file.delete();
                }


                File target;
                for(int e = this.maxBackupIndex - 1; e >= 1; --e) {
                    file = new File(super.fileName + "." + e);
                    if(file.exists()) {
                        target = new File(super.fileName + '.' + (e + 1));
                        LogLog.debug("Renaming file " + file + " to " + target);
                        file.renameTo(target);
                    }
                }

                target = new File(super.fileName + "." + 1);
                this.closeFile();
                file = new File(super.fileName);
                LogLog.debug("Renaming file " + file + " to " + target);
                file.renameTo(target);
            }

            try {
                this.setFile(super.fileName, false, super.bufferedIO, super.bufferSize);
            } catch (IOException var4) {
                LogLog.error("setFile(" + super.fileName + ", false) call failed.", var4);
            }
        } else {
            // 如果日期不一样
            if (!lastDateName.equals(sdf.format(new Date()))) {
                setFile(baseFilename);
                // 转日了
                this.closeFile();

                try {
                    this.setFile(super.fileName, false, super.bufferedIO, super.bufferSize);
                } catch (IOException var4) {
                    LogLog.error("setFile(" + super.fileName + ", false) call failed.", var4);
                }
            }
        }
    }

    public synchronized void setFile(String fileName, boolean append, boolean bufferedIO, int bufferSize)
            throws IOException {
        super.setFile(fileName, append, super.bufferedIO, super.bufferSize);
        if(append) {
            File f = new File(fileName);
            ((CountingQuietWriter)super.qw).setCount(f.length());
        }
    }

    public void setMaxBackupIndex(int maxBackups) {
        this.maxBackupIndex = maxBackups;
    }

    public void setMaximumFileSize(long maxFileSize) {
        this.maxFileSize = maxFileSize;
    }

    public void setMaxFileSize(String value) {
        this.maxFileSize = OptionConverter.toFileSize(value, this.maxFileSize + 1L);
    }

    protected void setQWForFiles(Writer writer) {
        super.qw = new CountingQuietWriter(writer, super.errorHandler);
    }

    protected void subAppend(LoggingEvent event) {
        long n = System.currentTimeMillis();

        // 时间转日，检查区间10秒左右
        if(n >= checkTime) {
            this.rollOver(false);
        }

        super.subAppend(event);

        // 文件满了
        if(super.fileName != null && ((CountingQuietWriter)super.qw).getCount() >= this.maxFileSize) {
            this.rollOver(true);
        }

    }
}
